import React from 'react';
import { Result, Button, Card, Typography, Space, Alert } from 'antd';
import { 
  BugOutlined, 
  ReloadOutlined, 
  HomeOutlined,
  WarningOutlined 
} from '@ant-design/icons';

const { Text, Paragraph } = Typography;

interface ErrorBoundaryState {
  hasError: boolean;
  error?: Error;
  errorInfo?: React.ErrorInfo;
  errorId?: string;
}

interface ErrorBoundaryProps {
  fallback?: React.ComponentType<ErrorFallbackProps>;
  onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
  children: React.ReactNode;
}

interface ErrorFallbackProps {
  error: Error;
  errorInfo?: React.ErrorInfo;
  resetError: () => void;
  errorId: string;
}

/**
 * 默认错误回退组件
 */
const DefaultErrorFallback: React.FC<ErrorFallbackProps> = ({ 
  error, 
  errorInfo, 
  resetError, 
  errorId 
}) => {
  const [showDetails, setShowDetails] = React.useState(false);

  const handleReload = () => {
    // 清理可能的错误状态
    try {
      localStorage.removeItem('extension-error-state');
      sessionStorage.clear();
    } catch (e) {
      console.warn('无法清理存储:', e);
    }
    
    // 重置错误状态
    resetError();
    
    // 如果是在popup或settings页面，重新加载
    if (window.location.href.includes('popup.html') || 
        window.location.href.includes('settings.html')) {
      window.location.reload();
    }
  };

  const handleGoHome = () => {
    resetError();
    // 如果在设置页面，尝试回到popup
    if (window.location.href.includes('settings.html')) {
      if (typeof chrome !== 'undefined' && chrome.runtime) {
        chrome.runtime.openOptionsPage();
      }
    }
  };

  const copyErrorDetails = async () => {
    const errorDetails = `
错误ID: ${errorId}
时间: ${new Date().toLocaleString()}
错误消息: ${error.message}
错误堆栈: ${error.stack}
组件堆栈: ${errorInfo?.componentStack || 'N/A'}
用户代理: ${navigator.userAgent}
    `.trim();

    try {
      await navigator.clipboard.writeText(errorDetails);
      console.log('错误详情已复制到剪贴板');
    } catch (e) {
      console.error('无法复制错误详情:', e);
    }
  };

  return (
    <div style={{ 
      padding: '20px', 
      minHeight: '300px',
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center'
    }}>
      <Result
        status="error"
        icon={<BugOutlined style={{ color: '#ff4d4f' }} />}
        title="应用遇到了错误"
        subTitle={
          <Space direction="vertical" size="small">
            <Text type="secondary">
              很抱歉，扩展遇到了意外错误。您可以尝试重新加载或联系开发者。
            </Text>
            <Text type="secondary" style={{ fontSize: '12px' }}>
              错误ID: {errorId}
            </Text>
          </Space>
        }
        extra={[
          <Button 
            type="primary" 
            icon={<ReloadOutlined />}
            onClick={handleReload}
            key="reload"
          >
            重新加载
          </Button>,
          <Button 
            icon={<HomeOutlined />}
            onClick={handleGoHome}
            key="home"
          >
            返回首页
          </Button>,
          <Button 
            type="link"
            onClick={() => setShowDetails(!showDetails)}
            key="details"
          >
            {showDetails ? '隐藏详情' : '查看详情'}
          </Button>
        ]}
      />
      
      {showDetails && (
        <Card 
          size="small"
          title={
            <Space>
              <WarningOutlined />
              <Text>错误详情</Text>
            </Space>
          }
          extra={
            <Button size="small" onClick={copyErrorDetails}>
              复制详情
            </Button>
          }
          style={{ marginTop: '16px' }}
        >
          <Space direction="vertical" style={{ width: '100%' }}>
            <Alert
              message="错误消息"
              description={
                <Paragraph code copyable style={{ margin: 0 }}>
                  {error.message}
                </Paragraph>
              }
              type="error"
              showIcon={false}
            />
            
            {error.stack && (
              <Alert
                message="错误堆栈"
                description={
                  <Paragraph 
                    code 
                    copyable 
                    style={{ 
                      margin: 0, 
                      maxHeight: '200px', 
                      overflow: 'auto',
                      fontSize: '11px',
                      lineHeight: '1.2'
                    }}
                  >
                    {error.stack}
                  </Paragraph>
                }
                type="warning"
                showIcon={false}
              />
            )}
            
            {errorInfo?.componentStack && (
              <Alert
                message="组件堆栈"
                description={
                  <Paragraph 
                    code 
                    copyable 
                    style={{ 
                      margin: 0, 
                      maxHeight: '150px', 
                      overflow: 'auto',
                      fontSize: '11px',
                      lineHeight: '1.2'
                    }}
                  >
                    {errorInfo.componentStack}
                  </Paragraph>
                }
                type="info"
                showIcon={false}
              />
            )}
          </Space>
        </Card>
      )}
    </div>
  );
};

/**
 * 全局错误边界组件
 * 用于捕获React组件树中的JavaScript错误
 */
export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
  private retryCount = 0;
  private maxRetries = 3;

  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {
    // 生成错误ID用于追踪
    const errorId = `ERR_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    
    return {
      hasError: true,
      error,
      errorId
    };
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    const errorId = this.state.errorId || 'UNKNOWN';
    
    // 更新状态包含错误信息
    this.setState({
      error,
      errorInfo,
      errorId
    });

    // 记录错误到控制台
    console.group(`🚨 React Error Boundary - ${errorId}`);
    console.error('Error:', error);
    console.error('Error Info:', errorInfo);
    console.error('Component Stack:', errorInfo.componentStack);
    console.groupEnd();

    // 尝试记录到扩展存储（用于错误报告）
    this.logErrorToStorage(error, errorInfo, errorId);

    // 调用外部错误处理器
    if (this.props.onError) {
      try {
        this.props.onError(error, errorInfo);
      } catch (handlerError) {
        console.error('错误处理器本身出错:', handlerError);
      }
    }

    // 发送错误到background script（如果需要）
    this.reportErrorToBackground(error, errorInfo, errorId);
  }

  /**
   * 将错误记录到本地存储
   */
  private async logErrorToStorage(error: Error, errorInfo: React.ErrorInfo, errorId: string) {
    try {
      const errorLog = {
        id: errorId,
        timestamp: new Date().toISOString(),
        message: error.message,
        stack: error.stack,
        componentStack: errorInfo.componentStack,
        url: window.location.href,
        userAgent: navigator.userAgent,
        retryCount: this.retryCount
      };

      // 获取现有错误日志
      const existingLogs = JSON.parse(
        localStorage.getItem('extension-error-logs') || '[]'
      );

      // 保留最近的10个错误日志
      const updatedLogs = [errorLog, ...existingLogs].slice(0, 10);
      
      localStorage.setItem('extension-error-logs', JSON.stringify(updatedLogs));
    } catch (storageError) {
      console.warn('无法保存错误日志到本地存储:', storageError);
    }
  }

  /**
   * 向background script报告错误
   */
  private reportErrorToBackground(error: Error, errorInfo: React.ErrorInfo, errorId: string) {
    try {
      if (typeof chrome !== 'undefined' && chrome.runtime) {
        chrome.runtime.sendMessage({
          type: 'ERROR_REPORT',
          payload: {
            id: errorId,
            message: error.message,
            stack: error.stack,
            componentStack: errorInfo.componentStack,
            timestamp: Date.now(),
            url: window.location.href
          }
        }).catch(() => {
          // 忽略发送失败，避免无限错误循环
        });
      }
    } catch (e) {
      // 忽略Chrome API错误
    }
  }

  /**
   * 重置错误状态
   */
  resetError = () => {
    this.retryCount++;
    
    if (this.retryCount <= this.maxRetries) {
      this.setState({
        hasError: false,
        error: undefined,
        errorInfo: undefined,
        errorId: undefined
      });
    } else {
      console.warn('已达到最大重试次数，停止自动恢复');
    }
  };

  render() {
    if (this.state.hasError && this.state.error) {
      const FallbackComponent = this.props.fallback || DefaultErrorFallback;
      
      return (
        <FallbackComponent
          error={this.state.error}
          errorInfo={this.state.errorInfo}
          resetError={this.resetError}
          errorId={this.state.errorId || 'UNKNOWN'}
        />
      );
    }

    return this.props.children;
  }
}

/**
 * 高阶组件：为组件添加错误边界
 */
export function withErrorBoundary<P extends object>(
  Component: React.ComponentType<P>,
  errorBoundaryProps?: Omit<ErrorBoundaryProps, 'children'>
) {
  const WrappedComponent = (props: P) => (
    <ErrorBoundary {...errorBoundaryProps}>
      <Component {...props} />
    </ErrorBoundary>
  );

  WrappedComponent.displayName = `withErrorBoundary(${Component.displayName || Component.name})`;
  
  return WrappedComponent;
}

export default ErrorBoundary;